package com.swf.seed.algorithms.tree;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;

import org.springframework.util.StopWatch;

/**
 * ClassName: SensitivewordFilter <br/>
 * Function: 敏感词过滤. <br/>
 * Reason: 将所有敏感词包装成一个森林对象，森林包含很多树，每个数的key即为敏感词的首字符。<br/>
 * 将输入的内容从第一个字符开始遍历，如果该字符包含在森林中，找出该棵树。<br/>
 * 1、判断字符是否为敏感词结尾；如果结尾，则记录：如果未非结尾，判断下一个字符是否在该棵树上。
 * 2、如果不为敏感词，则退出，继续判断下一个字符
 * date: 2015-1-22 下午5:22:25 <br/>
 *
 * @author shenwf10476
 * @version 
 * @since JDK 1.6
 */
public class SensitivewordFilter {
	public static void main(String[] args) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(SensitivewordFilter.class.getResourceAsStream("/sensitivewords.txt"), "utf-8"));
		Set<String> keySet = new HashSet<String>();
		String line ;
		while ((line = reader.readLine())!=null){
			keySet.add(line.trim());
		}
		String[] words = keySet.toArray(new String[keySet.size()]);
		Forest forest = dealWords(words);
		reader = new BufferedReader(new InputStreamReader(SensitivewordFilter.class.getResourceAsStream("/content.txt"), "utf-8"));
		StringBuilder content = new StringBuilder();
		while ((line = reader.readLine())!=null){
			content.append(line.trim());
		}
		dealSensitiveWords(forest,content.toString());
	}

	/**
	 * @param forest
	 */
	private static void dealSensitiveWords(Forest forest,String content) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		char current;
		CharBuilder builder = new CharBuilder();
		CharBuilder chars = new CharBuilder(content);
		Character topChar;
		Set<String>  sensitivewords = new HashSet<String>();
		int sensitivewordsCount = 0;
		while ((topChar=chars.pop())!=null){
			if (forest.contains(topChar)){
				builder.clear();
				Node tree = forest.getTreeMap().get(topChar);
				builder.append(topChar);
				int j=0;
				while (true){
					if (tree.isEnd()){
						sensitivewords.add(builder.toString());
						sensitivewordsCount++;
					}
					if (chars.size()<=j){
						break;
					}
					current = chars.get(j++);
					builder.append(current);
					if (tree.containsChild(current)){
						tree = tree.getChild((Character)current);
					}else{break;}
				}
			}
		}
		stopWatch.stop();
		System.out.println("文本长度："+ content.length());
		System.out.println("处理时间："+ stopWatch.getTotalTimeMillis()+"ms");
		System.out.println("敏感词总数量："+ sensitivewordsCount);
		System.out.println("敏感词单词数："+ sensitivewords.size());
		for (String word:sensitivewords){
			System.out.print(word+",");
		}
	}

	private static Forest dealWords(String[] words) {
		Forest forest = new Forest();
		char[] cs;
		Node[] tree = new Node[words.length];
		for (int i=0;i<words.length;i++){
			cs = words[i].toCharArray();
			tree[i] = translateChars2Tree(cs);
			forest.addOrUpdateTree(tree[i]);
		}
		return forest;
	}

	private static Node translateChars2Tree(char[] cs) {
		Node[] nodes = new Node[cs.length] ;
		for (int i=0;i<nodes.length;i++){
			nodes[i] = new Node();
			nodes[i].setHeight(i+1);
		}
		for (int i=0;i<cs.length;i++){
			nodes[i].setKey(cs[i]);
		}
		for (int i=0;i<cs.length-1;i++){
			nodes[i].addChild(nodes[i+1]);
		}
		nodes[cs.length-1].setEnd(true);
		for (int i=1;i<cs.length;i++){
			nodes[i].setParent(nodes[i-1]);
		}
		return nodes[0];
		
	}
}
